package com.secsbrain.development.web.controller;

import com.secsbrain.cmdb.client.iface.AppInfoService;
import com.secsbrain.common.ResponseResult;
import com.secsbrain.common.utils.DateTimeUtils;
import com.secsbrain.deploy.client.iface.DeployService;
import com.secsbrain.deploy.client.iface.ModelService;
import com.secsbrain.development.biz.BuilderService;
import com.secsbrain.development.biz.IDeployApprovalService;
import com.secsbrain.development.biz.IProjectAppService;
import com.secsbrain.development.biz.constant.AppType;
import com.secsbrain.development.biz.constant.EnumDefinition;
import com.secsbrain.development.biz.exception.BizMessageException;
import com.secsbrain.development.biz.utils.DingUtils;
import com.secsbrain.development.dal.model.DeployApproval;
import com.secsbrain.development.remote.SsoRemoteService;
import com.secsbrain.development.web.utils.BranchUtils;
import com.secsbrain.frame.lock.Callback;
import com.secsbrain.frame.lock.DistributedLockTemplate;
import com.secsbrain.sso.core.SsoHelper;
import com.secsbrain.sso.model.dto.system.UserDTO;
import com.secsbrain.sso.model.dto.system.UserDetailDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSON;
import com.secsbrain.cmdb.client.model.AppDetail;
import com.secsbrain.cmdb.client.model.Server;
import com.secsbrain.common.concurrent.ExecutorManager;
import com.secsbrain.common.ErrorCodeEnum;
import com.secsbrain.common.ResponseVo;
import com.secsbrain.deploy.client.model.BatchBuildResult;
import com.secsbrain.deploy.client.model.BuildLog;
import com.secsbrain.deploy.client.model.BuildModelDto;
import com.secsbrain.deploy.client.model.BuildQuery;
import com.secsbrain.deploy.client.model.BuildRecord;
import com.secsbrain.deploy.client.model.HealthDto;
import com.secsbrain.development.client.model.TestResult;
import com.secsbrain.development.web.dto.BuildLogDTO;
import com.secsbrain.development.web.dto.BuildModelDTO;
import com.secsbrain.development.web.dto.BuildSnapshotDTO;
import com.secsbrain.development.web.dto.CommandContext;
import com.secsbrain.development.web.dto.ProjectTaskDTO;
import com.secsbrain.development.web.dto.SingleTaskDTO;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

@RequestMapping("api/build")
@RestController
@Api(value = "build", tags = "自助发布")
public class BuilderController {

    private static final Logger LOGGER = LoggerFactory.getLogger(BuilderController.class);

    @Autowired
    BuilderService builderService;

    @Autowired
    IDeployApprovalService deployApprovalService;

    @Autowired
    DeployService deployService;

    @Autowired
    ModelService modelService;

    @Autowired
    AppInfoService cmdbRemoteService;

    @Autowired
    SsoRemoteService userServiceFacade;

    @Autowired
    IProjectAppService planService;

    @Autowired
    DistributedLockTemplate distributedLockTemplate;

    @Value("${resource.agent.url:}")
    private String agentUrl;

    @Value("${dingtalk.group:}")
    private String dingtalkGroupUrl;

    @Value("${passport.key:123456}")
    private String passportKey;

    /**
     * @api {POST} /api/build/groupA  dotnet系统灰度发布
     * @apiDescription 注意：只有当系统类型是dotnet且开启了切流发布才能调用此接口
     * @apiGroup BUILD
     * @apiParam {String{20}} appName   应用名称，如www
     * @apiParam {Number{11}} appId     应用id
     * @apiParam {String{5}}  envId     发布环境，如pre
     * @apiParam {String{5}}  gitBranch git分支
     * @apiParam {Number{11}} [id]  构建记录ID，发布按钮在构建记录里则需必传
     * @apiParam {String{200}} [desc] 发布说明及影响面，当发布环境为prod时必传
     */
    @ResponseBody
    @SuppressWarnings("rawtypes")
    @RequestMapping(value = "/groupA", method = RequestMethod.POST)
    @ApiIgnore
    public ResponseResult doExecGroupA(@Valid @RequestBody SingleTaskDTO param) {
        if (StringUtils.isEmpty(param.getAppName())) {
            throw new BizMessageException("appName不能为空");
        }
        if (param.getAppId() == null) {
            throw new BizMessageException("appId不能为空");
        }
        if (StringUtils.isEmpty(param.getEnv())) {
            throw new BizMessageException("env不能为空");
        }

        String checkResult = BranchUtils.checkBranchName(param.getEnv(), param.getGitBranch());
        if (StringUtils.isNotEmpty(checkResult)) {
            throw new BizMessageException(checkResult);
        }

        ResponseVo<AppDetail> appDetailVo = cmdbRemoteService.queryAppDetailById(param.getAppId());
        if (!appDetailVo.isSuccess() || appDetailVo.getData() == null) {
            return new ResponseResult<>(appDetailVo.getErrorCode(), appDetailVo.getMsg());
        }

        AppDetail appDetail = appDetailVo.getData();

        if ("prod".equals(param.getEnv()) || "pre".equals(param.getEnv())) {
            if ("A".equals(appDetail.getLevel()) || "B".equals(appDetail.getLevel())) {
                if (param.getId() == null) {
                    throw new BizMessageException("审批id不能为空");
                }
            }
        }

        UserDetailDTO userDTO = SsoHelper.currentUser();

        return (ResponseResult) distributedLockTemplate.execute("doExecGroupA_" + param.getAppName() + "_" + param.getEnv(), 500, new Callback() {

            @Override
            public Object onGetLock() throws InterruptedException {
                if (param.getId() != null) {
                    ResponseVo<BuildRecord> buildRecordVo = deployService.queryBuildRecordByBuildId(param.getId(),param.getEnv());

                    //判断是否完成发布审核
                    DeployApproval deployApproval = deployApprovalService.selectById(buildRecordVo.getData().getApprovalId());
                    if (deployApproval == null) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "没有查询到审批记录");
                    }
                    if (!EnumDefinition.ApprovalStatus.AGREE.getCode().equals(deployApproval.getStatus())) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "审批状态不正确");
                    }
                    //判断应用和环境信息是否一致
                    if (!param.getAppId().equals(deployApproval.getAppId())
                            || !param.getEnv().equals(deployApproval.getEnv())) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "应用或环境信息和审批记录不一致");
                    }
                    param.setGitBranch(deployApproval.getBranch());
                    param.setAppId(deployApproval.getAppId());
                    ResponseVo<AppDetail> appDetailVo = cmdbRemoteService.queryAppDetailById(param.getAppId());
                    if (appDetailVo.isSuccess() && appDetailVo.getData() != null) {
                        param.setAppName(appDetailVo.getData().getName());
                    }
                    param.setEnv(deployApproval.getEnv());
                }
                LOGGER.debug("A组发布开始。。。appName：{}", param.getAppName());

                ResponseVo<BuildModelDto> buildModelVo = modelService.queryBuildModelByApp(param.getAppId(),param.getEnv());
                Map buildModeMap = JSON.parseObject(buildModelVo.getData().getModelJson(), Map.class);

                if (((String) buildModeMap.get("switchEnvName")).equals(param.getEnv())) {
                    param.setGroupName("A");
                }

                CommandContext commandContext = builderService.execSingleTask(param);
                if (commandContext.isCreated()) {
                    noticeDingGroup(param, "A", param.getDesc(), userDTO.getNickname(), appDetail);
                    return new ResponseResult<>(commandContext);

                } else {
                    return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), commandContext.getMessage());
                }
            }

            @Override
            public Object onTimeout() throws InterruptedException {
                LOGGER.debug("doExecGroupA重复提交，等待超时！");
                return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "此应用正在执行发布，请稍后重试");
            }

        });

    }

    /**
     * @api {POST} /api/build/groupB  dotnet系统全量发布
     * @apiGroup BUILD
     * @apiParam {Number{11}} groupId     分组id
     * @apiParam {String{5}}  envName     发布环境，如pre
     * @apiParam {Number{11}} [bBuildId]  构建记录ID，发布按钮在构建记录里则需必传
     */
    @RequestMapping(value = "/groupB", method = RequestMethod.POST)
    @ApiIgnore
    public ResponseResult doExecGroupB(Long groupId, String envName, Long bBuildId) {
        if (groupId == null) {
            throw new BizMessageException("groupId不能为空");
        }
        if (StringUtils.isEmpty(envName)) {
            throw new BizMessageException("env不能为空");
        }

        UserDetailDTO userDTO = SsoHelper.currentUser();

        return (ResponseResult) distributedLockTemplate.execute("doExecGroupB_" + groupId + "_" + envName, 500, new Callback() {

            @Override
            public Object onGetLock() throws InterruptedException {
                //判断是否完成发布审核
                if (bBuildId != null) {
                    ResponseVo<BuildRecord> buildRecordVo = deployService.queryBuildRecordByBuildId(bBuildId,envName);
                    //判断是否完成发布审核
                    DeployApproval deployApproval = deployApprovalService.selectById(buildRecordVo.getData().getApprovalId());
                    if (deployApproval == null) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "没有查询到审批记录");
                    }
                    if (!EnumDefinition.ApprovalStatus.AGREE.getCode().equals(deployApproval.getStatus())) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "审批状态不正确");

                    }
                    //判断应用和环境信息是否一致
                    if (!envName.equals(deployApproval.getEnv())) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "环境信息和审批记录不一致");
                    }
                }

                Object[] params = {groupId, envName, bBuildId};
                LOGGER.debug("B组发布开始。。。groupId:{},envName:{},bBuildId:{}", params);
                CommandContext commandContext = builderService.execBGroup(groupId, envName, bBuildId);
                if (commandContext.isCreated()) {
                    SingleTaskDTO param = new SingleTaskDTO();
                    param.setAppName(commandContext.getMessage());
                    param.setAppId(commandContext.getAppId());
                    param.setEnv(envName);

                    ResponseVo<AppDetail> appDetailVo = cmdbRemoteService.queryAppDetailById(param.getAppId());
                    if (!appDetailVo.isSuccess() || appDetailVo.getData() == null) {
                        return new ResponseResult<>(appDetailVo.getErrorCode(), appDetailVo.getMsg());
                    }

                    AppDetail appDetail = appDetailVo.getData();
                    noticeDingGroup(param, "B", param.getDesc(), userDTO.getNickname(), appDetail);
                    return new ResponseResult<>(commandContext);
                } else {
                    return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), commandContext.getMessage());
                }
            }

            @Override
            public Object onTimeout() throws InterruptedException {
                LOGGER.debug("doExecGroupB重复提交，等待超时！");
                return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "此应用正在执行发布，请稍后重试");
            }

        });

    }

    @RequestMapping(value = "/grayPercent", method = RequestMethod.POST)
    @ApiIgnore
    public ResponseResult grayPercent(Long groupId, Integer percent) {
        if (groupId == null || percent == null) {
            throw new BizMessageException("groupId或者percent不能为空");
        }
        ResponseVo<Integer> finalPercentVo = deployService.percentRelease(groupId, percent);
        if (!finalPercentVo.isSuccess()) {
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), finalPercentVo.getMsg());
        }
        return new ResponseResult<>(finalPercentVo.getData());
    }

    /**
     * @api {POST} /api/build/singleton  一键发布
     * @apiGroup BUILD
     * @apiParam {String{20}} appName   应用名称，如www
     * @apiParam {Number{11}} appId     应用id
     * @apiParam {String{5}}  envId     发布环境，如pre
     * @apiParam {String{5}}  gitBranch git分支
     * @apiParam {Number{11}} [id]  构建记录ID，发布按钮在构建记录里则需必传
     * @apiParam {String{200}} [desc] 发布说明及影响面，当发布环境为prod时必传
     */
    @RequestMapping(value = "/singleton", method = RequestMethod.POST)
    @ApiOperation(value = "一键部署", notes = "一键部署")
    public ResponseResult doExecSingleTask(@RequestBody SingleTaskDTO param) {
        if (StringUtils.isEmpty(param.getAppName())) {
            throw new BizMessageException("appName不能为空");
        }
        if (param.getAppId() == null) {
            throw new BizMessageException("appId不能为空");
        }
        if (StringUtils.isEmpty(param.getEnv())) {
            throw new BizMessageException("env不能为空");
        }

        if (StringUtils.isEmpty(param.getGitBranch())) {
            throw new BizMessageException("分支不能为空");
        }

        //TODO 发布分支名规则限制
//		String checkResult=BranchUtils.checkBranchName(param.getEnv(),param.getGitBranch());
//		if(StringUtils.isNotEmpty(checkResult)){
//			throw new BizMessageException(checkResult);
//		}

        ResponseVo<AppDetail> appDetailVo = cmdbRemoteService.queryAppDetailById(param.getAppId());
        if (!appDetailVo.isSuccess() || appDetailVo.getData() == null) {
            return new ResponseResult<>(appDetailVo.getErrorCode(), appDetailVo.getMsg());
        }

        AppDetail appDetail = appDetailVo.getData();

//        if ("prod".equals(param.getEnv()) || "pre".equals(param.getEnv())) {
//            if (("A".equals(appDetail.getLevel()) || "B".equals(appDetail.getLevel()))) {
//                if (param.getId() == null) {
//                    throw new BizMessageException("审批id不能为空");
//                }
//            }
//        }

        UserDetailDTO userDTO = SsoHelper.currentUser();

        return (ResponseResult) distributedLockTemplate.execute("doExecSingleTask_" + param.getAppId() + "_" + param.getEnv(), 500, new Callback() {

            @Override
            public Object onGetLock() {
                //id不为空说明是审批的情况
                if (param.getId() != null) {
                    ResponseVo<BuildRecord> buildRecordVo = deployService.queryBuildRecordByBuildId(param.getId(),param.getEnv());

                    //判断是否完成发布审核
                    DeployApproval deployApproval = deployApprovalService.selectById(buildRecordVo.getData().getApprovalId());
                    if (deployApproval == null) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "没有查询到审批记录");
                    }
                    if (!EnumDefinition.ApprovalStatus.AGREE.getCode().equals(deployApproval.getStatus())) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "审批状态不正确");
                    }
                    //判断应用和环境信息是否一致
                    if (!param.getAppId().equals(deployApproval.getAppId())
                            || !param.getEnv().equals(deployApproval.getEnv())) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "应用或环境信息和审批记录不一致");
                    }
                    param.setGitBranch(deployApproval.getBranch());
                    param.setAppId(deployApproval.getAppId());
                    param.setAppName(appDetail.getName());
                    param.setEnv(deployApproval.getEnv());

                    String checkResult = BranchUtils.checkBranchName(param.getEnv(), param.getGitBranch());
                    if (StringUtils.isNotEmpty(checkResult)) {
                        return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), checkResult);
                    }
                }

                CommandContext commandContext = builderService.execSingleTask(param);
                if (commandContext.isCreated()) {
                    noticeDingGroup(param, null, param.getDesc(), userDTO.getNickname(), appDetail);
                    return new ResponseResult<>(commandContext);
                } else {
                    return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), commandContext.getMessage());
                }
            }

            @Override
            public Object onTimeout() {
                LOGGER.debug("doExecSingleTask重复提交，等待超时！");
                return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "此应用正在执行发布，请稍后重试");
            }

        });

    }

    private void noticeDingGroup(SingleTaskDTO param, String groupName, String influence, String creator, AppDetail appDetail) {
        ExecutorManager.getInstance().execute(() -> {
            try {
                List<String> mobileList = new ArrayList<>();
                if("pre".equals(param.getEnv())||"prod".equals(param.getEnv())){
                    //TODO  环境标识暂时写死
                    if (appDetail.getOwnerId() != null) {
                        ResponseResult<UserDTO> userResult = userServiceFacade.getUserDTO(appDetail.getOwnerId());
                        if (userResult.getData() != null && userResult.getData().getPhoneNum() != null) {
                            mobileList.add(userResult.getData().getPhoneNum());
                        }
                    }
                    if (appDetail.getQualityId() != null) {
                        ResponseResult<UserDTO> userResult = userServiceFacade.getUserDTO(appDetail.getQualityId());
                        if (userResult.getData() != null && userResult.getData().getPhoneNum() != null) {
                            mobileList.add(userResult.getData().getPhoneNum());
                        }
                    }
                }

                String desc = appDetail.getDesc() != null ? appDetail.getDesc() : param.getAppName();
                String prefix = "【"+param.getEnv()+"环境】"+"发布公告：" + DateTimeUtils.parseDateAsString(new Date(), "MM月dd日HH:mm") + "  " + param.getAppName() + "(" + desc + ")";

                String content="";
                if (StringUtils.isNotEmpty(influence)) {
                    if ("A".equals(groupName)) {
                        String word = "A组";
//						if(appDetail!=null&&SystemTypeEnums.DOTNET.toString().equals(appDetail.getSystemType())){
//							word="灰度";
//						}
                        content= prefix + word + "发布：【更新内容及影响：" + influence + "】，请知悉。【执行人】：" + creator;
                    } else if ("B".equals(groupName)) {
                        String word = "B组";
//						if(appDetail!=null&&SystemTypeEnums.DOTNET.toString().equals(appDetail.getSystemType())){
//							word="全量";
//						}
                        content= prefix + word + "发布：发布时可能会短暂影响线上相关功能，请知悉。【执行人】：" + creator;
                    } else {
                        content= prefix + "发布：【更新内容及影响：" + influence + "】，请知悉。【执行人】：" + creator;
                    }
                } else {
                    content=prefix + "发布，请知悉。执行人：" + creator;
                }

                ResponseVo<?> res=DingUtils.groupNotice(appDetail.getTenantCode(),content,mobileList);
                LOGGER.debug("钉钉群通知返回结果：" + JSON.toJSONString(res));
            } catch (Exception e) {
                LOGGER.error("", e);
            }
        });

    }

    /**
     * @api {GET} /api/build/up  springcloud手动上线
     * @apiGroup BUILD
     * @apiParam {Number{11}} appId   应用id
     * @apiParam {String{5}}  env     环境名称
     * @apiParam {String{32}} host    主机地址，如10.0.11.58
     */
    @RequestMapping(value = "/up", method = RequestMethod.GET)
    @ApiIgnore
    public ResponseResult up(Long appId, String env, String host) {
        ResponseVo<?> responseVo = deployService.serverUp(appId, host);
        if (!responseVo.isSuccess()) {
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), responseVo.getMsg());
        }
        return new ResponseResult<>();
    }

    /**
     * @api {GET} /api/build/health  springcloud健康检查
     * @apiGroup BUILD
     * @apiParam {Number{11}} appId   应用id
     * @apiParam {String{5}}  env     环境名称
     * @apiParam {String{32}} [host]    主机地址，如10.0.11.58
     */
    @RequestMapping(value = "/health", method = RequestMethod.GET)
    @ApiOperation(value = "springcloud健康检查", notes = "springcloud健康检查")
    public ResponseResult health(Long appId, String env, String host) {
        if (appId == null) {
            throw new BizMessageException("appId不能为空");
        }
        if (StringUtils.isEmpty(env)) {
            throw new BizMessageException("env不能为空");
        }

        HealthDto healthDto = new HealthDto();
        healthDto.setAppId(appId);
        if (StringUtils.isNotEmpty(host)) {
            List<String> hostList = new ArrayList<String>();
            hostList.add(host);
            healthDto.setHostList(hostList);
        } else {
            ResponseVo<AppDetail> appDetailVo = cmdbRemoteService.queryAppDetailById(appId);
            if (!appDetailVo.isSuccess() || appDetailVo.getData() == null) {
                return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "没有查询到应用详情");
            }
            AppDetail appDetail = appDetailVo.getData();
            List<Server> serverList = appDetail.getServerList();
            List<String> hostList = new ArrayList<String>();
            for (Server server : serverList) {
                if (env.equals(server.getEnvName())) {
                    hostList.add(server.getHostName());
                }
            }
            healthDto.setHostList(hostList);
        }
        ResponseVo<?> responseVo = deployService.healthCheck(healthDto);
        if (!responseVo.isSuccess()) {
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), responseVo.getMsg());
        }
        return new ResponseResult<>();
    }

    @RequestMapping(value = "/project", method = RequestMethod.POST)
    @ApiIgnore
    public ResponseResult doExecProject(@Valid @RequestBody ProjectTaskDTO param) {
        List<Long> newAppIds = new ArrayList<Long>();
        for (Long appId : param.getAppIds()) {
            if (appId != null) {
                newAppIds.add(appId);
            }
        }
        Assert.notEmpty(newAppIds, "至少需要勾选一个应用");
        param.setAppIds(newAppIds);

        try {
            BatchBuildResult batchBuildResult = builderService.execPublishProject(param);

            if (batchBuildResult.getTotalCount() != batchBuildResult.getSuccessCount()) {
                Set<Long> keySet = batchBuildResult.getFailAppMsg().keySet();
                for (Long appId : keySet) {
                    LOGGER.warn("appId:" + appId + ",msg:" + batchBuildResult.getFailAppMsg().get(appId));
                }
            }

            return new ResponseResult<>("发布了" + batchBuildResult.getTotalCount() + "个应用，执行了" + batchBuildResult.getSuccessCount() + "个");
        } catch (Exception e) {
            LOGGER.error("构建失败：" + e.getMessage());
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), e.getMessage());
        }
    }

    @RequestMapping(value = "/buildModel", method = RequestMethod.POST)
    @ApiIgnore
    public ResponseResult buildModel(@RequestParam(required = false) Long appId,
                                     @RequestParam(required = false) AppType appType,
                                     @RequestParam(required = false) String branch,
                                     @RequestParam(required = false, defaultValue = "false") boolean ignore) {
        BuildModelDTO modelRecord = new BuildModelDTO();
        return new ResponseResult<>(modelRecord);
    }

    @RequestMapping(value = "/records", method = RequestMethod.GET)
    @ApiOperation(value = "单应用发布记录查询", notes = "单应用发布记录查询")
    public ResponseResult<List<BuildSnapshotDTO>> records(@RequestParam(value = "projectId", required = false) Long projectId,
                                                          @ApiParam("应用ID") @RequestParam(value = "appId", required = false) Long appId,
                                                          @ApiParam("环境名称") @RequestParam(value = "env", required = false) String env) {
        boolean findByAppIdAndEnvId = appId != null && env != null;
        boolean findByProjectId = projectId != null;
        if (!findByProjectId && !findByAppIdAndEnvId) {
            throw new BizMessageException(ErrorCodeEnum.ERROR_COMMON_PARAM.getCode() + "", "发布计划ID或者应用ID");
        }

        List<BuildSnapshotDTO> records = builderService.buildRecords(projectId, appId, env);
        return new ResponseResult<>(records);
    }

    /**
     * 功能描述: <br>
     * 所有应用的发布记录
     *
     * @param pageNo
     * @param length
     * @param sortBy
     * @param descending
     * @param deployStatus
     * @param buildQuery
     * @return
     */
    @RequestMapping(value = "/recordList", method = RequestMethod.GET)
    @ApiOperation(value = "发布记录查询", notes = "发布记录查询")
    public ResponseResult<ResponseVo<List<BuildRecord>>> recordList(@RequestParam(name = "pageNo", defaultValue = "1") int pageNo,
                                                                    @RequestParam(value = "length", defaultValue = "10") int length,
                                                                    @RequestParam("sortBy") String sortBy,
                                                                    @RequestParam(value = "descending") String descending,
                                                                    @RequestParam(value = "deployStatus") String deployStatus,
                                                                    BuildQuery buildQuery) {
        if (org.apache.commons.lang.StringUtils.isNotEmpty(deployStatus) && !"null".equals(deployStatus)) {
            buildQuery.setStatus(Integer.parseInt(deployStatus));
        }
        ResponseVo<List<BuildRecord>> buildRecordVo = deployService.queryAllBuildList(pageNo, length, sortBy, descending,
                buildQuery.getAppName(),buildQuery.getEnvName(),buildQuery.getBranchName(),buildQuery.getStartDate(),
                buildQuery.getEndDate(),buildQuery.getStatus(),buildQuery.getCreateName());
        return new ResponseResult<>(buildRecordVo);
    }

    /**
     * 功能描述: <br>
     * 测试报告
     *
     * @param appId
     * @return
     */
    @RequestMapping(value = "/testResult/{appId}", method = RequestMethod.GET)
    @ApiIgnore
    public ResponseResult testResult(@PathVariable("appId") Long appId) {
        ResponseVo<TestResult> responseVo = planService.getTestResult(appId, null);

        if (!responseVo.isSuccess()) {
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), responseVo.getMsg());
        }
        if (responseVo.getData() != null) {
            TestResult testResult = responseVo.getData();
            if (testResult.getCode() == 0) {
                ResponseResult responseResult = new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_CHECK.getCode(), "不满足发布条件");
                responseResult.setData(testResult.getDetailList());
                return responseResult;
            }
            return new ResponseResult<>();
        }
        return new ResponseResult<>();
    }

    /**
     * 功能描述: <br>
     * 查看日志记录
     *
     * @param snapshotId
     * @param envName
     * @param start
     * @return
     */
    @RequestMapping(value = "/checkLog", method = RequestMethod.GET)
    @ApiOperation(value = "查看日志记录", notes = "查看日志记录")
    public ResponseResult<?> checkLog(Long snapshotId, String envName, Long start) {
        if (start == null) {
            start = 0L;
        }
        ResponseVo<BuildLog> buildLogVo=deployService.getBuildLog(snapshotId, start,envName);
        if(!buildLogVo.isSuccess()){
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_SYSTEM.getCode(), buildLogVo.getMsg());
        }

        BuildLogDTO buildLogDTO = new BuildLogDTO();
        ResponseVo<BuildRecord> buildRecordVo = deployService.queryBuildRecordByBuildId(snapshotId,envName);
        if(!buildRecordVo.isSuccess()){
            return new ResponseResult<>(ErrorCodeEnum.ERROR_COMMON_SYSTEM.getCode(), buildRecordVo.getMsg());
        }
        buildLogDTO.setBuildStatus(buildRecordVo.getData().getStatus());
        BuildLog buildLog = buildLogVo.getData();
        buildLogDTO.setLogContent(buildLog.getLogContent());
        buildLogDTO.setxMoreData(buildLog.getxMoreData());
        buildLogDTO.setxTextSize(buildLog.getxTextSize());
        return new ResponseResult<>(buildLogDTO);
    }

}
